﻿using Modules.Reports;
using PmSoft.Quartz;
using Quartz;

namespace ManagementApi.Jobs;

/// <summary>
/// 项目月统计报表
/// </summary>
[DisallowConcurrentExecution]//不可并行执行
[JobDescription("0 0 00 * * ?")]//必须每天0点执行
//[JobDescription("0 */1 * * * ?")]//测试1分钟执行1次
public class GenerateProjectMonthReportJob : IJob
{
    private readonly ReportProjectMonthService reportProjectMonthService;
    private readonly ILogger logger;

    public GenerateProjectMonthReportJob(ReportProjectMonthService reportProjectMonthService, ILogger<GenerateProjectMonthReportJob> logger)
    {
        this.reportProjectMonthService = reportProjectMonthService;
        this.logger = logger;
    }

    /// <summary>
    /// 执行
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task Execute(IJobExecutionContext context)
    {
        DateTime date = DateTime.Now.AddDays(-1);
        
        int month = Convert.ToInt32(date.ToString("yyyyMM"));
        IEnumerable<int> projectIds;
        while ((projectIds = reportProjectMonthService.GetProjectIdsInNoUpdate(month)).Count() > 0)
        {
            foreach (int projectId in projectIds)
            {
                try
                {
                    reportProjectMonthService.Generate(projectId, date);
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "项目月统计报表执行失败，projectId={0}，错误消息={1}", projectId, ex.Message);
                    throw;
                }
            }
        }


        #region 注释掉的
        //try
        //{
        //    //DateTime time = Convert.ToDateTime("2024-03-07 00:00:00");//测试用
        //    DateTime time = DateTime.Now;
        //    DateTime month = time.Date;
        //    DateTime startTime;
        //    DateTime endTime;
        //    //1.判断日期是否为1号
        //    if (time.Day == 1)
        //    {
        //        #region 统计上月   1号0点到当月最后一天23.59.59

        //        month = time.AddMonths(-1);
        //        month = Convert.ToDateTime(month.ToString("yyyy-MM-01"));
        //        startTime = Convert.ToDateTime(time.AddMonths(-1).ToString("yyyy-MM-01 00:00:00"));
        //        endTime = Convert.ToDateTime(time.ToString("yyyy-MM-01 00:00:00"));

        //        #endregion 统计上月   1号0点到当月最后一天23.59.59
        //    }
        //    else
        //    {
        //        #region 统计当月   1号0点到昨天23.59.59

        //        month = Convert.ToDateTime(time.ToString("yyyy-MM-01"));
        //        startTime = Convert.ToDateTime(time.ToString("yyyy-MM-01 00:00:00"));
        //        endTime = Convert.ToDateTime(time.ToString("yyyy-MM-dd 00:00:00"));

        //        #endregion 统计当月   1号0点到昨天23.59.59
        //    }
        //    //2.查询month对应的数据是否存在，若存在则全部删除
        //    IEnumerable<ReportProjectMonth> reportProjectMonths = reportProjectMonthService.GetReportProjectsMonthsByMonth(Convert.ToInt32((month).ToString("yyyyMM")));
        //    reportProjectMonthService.Deleted(reportProjectMonths.Select(a => a.Id));

        //    IEnumerable<ProjectInfo> projectInfos = projectService.GetAll();
        //    IEnumerable<BankSpecialAccountInfo> projectSpecialAccounts = projectSpecialAccountService.GetProjectSpecialAccountByProjectIds(projectInfos.Select(a => a.ProjectId));
        //    IEnumerable<ProjectStatusChangeRecord> projectStatusChangeRecords = projectStatusChangeRecordService.GetProjectStatusChangeRecordsByProjectIds(projectInfos.Select(a => a.ProjectId));
        //    IEnumerable<ProjectGroupMember> members = projectGroupMemberService.GetProjectGroupMembersByProjectIds(projectInfos.Select(a => a.ProjectId)).Where(a => a.Status == 进出场状态.进场);
        //    IEnumerable<CheckinWorkHours> checkinWorkHours = checkinWorkHoursService.GetCheckinWorkHoursByProjectIdsAndMonth(projectInfos.Select(a => a.ProjectId), month.ToString("yyyyMM"));
        //    reportProjectMonths = reportProjectMonthService.GetAll();

        //    applicationContext.Transaction.Begin();
        //    foreach (var project in projectInfos)
        //    {
        //        ReportProjectMonth entity = new();
        //        entity.Month = Convert.ToInt32(month.ToString("yyyyMM"));
        //        entity.ProjectId = project.ProjectId;
        //        var projectSpecialAccount = projectSpecialAccounts.FirstOrDefault(a => a.ProjectId == project.ProjectId);
        //        entity.SpecialAccountStatus = projectSpecialAccount?.AccountStatus == 专户状态.正常 ? 落实状态.已落实 : 落实状态.已落实;

        //        entity.DaysThisMonthUnderConstruction = projectStatusChangeRecords.Where(a => a.ProjectId == project.ProjectId).GetStatusDays(ProjectConstants.项目状态.在建, month, startTime, endTime);
        //        entity.DaysThisMonthShutDown = projectStatusChangeRecords.Where(a => a.ProjectId == project.ProjectId).GetStatusDays(ProjectConstants.项目状态.停工, month, startTime, endTime);

        //        #region 考勤状态

        //        entity.CheckinStatus = 落实状态.无需核实;
        //        if (entity.DaysThisMonthUnderConstruction > 0)
        //        {
        //            entity.CheckinStatus = checkinWorkHoursService.GetKeyPositionCheckinStatus(members, checkinWorkHours, project.ProjectId, false);
        //            entity.NumberAttendanceRequired = members.Where(a => a.ProjectId == project.ProjectId).Count();
        //            entity.ActualAttendance = checkinWorkHours.Where(a => a.ProjectId == project.ProjectId && members.Where(a => a.ProjectId == project.ProjectId).Select(a => a.Id).Contains(a.MemberId)).Count();
        //        }

        //        #endregion 考勤状态

        //        entity.WageStatus = 落实状态.无需核实;

        //        #region 进账状态

        //        var bankStatistic = new BankSpecialAccountStatisticMonth();
        //        if (!string.IsNullOrEmpty(projectSpecialAccount?.BankNo))
        //        {
        //            bankStatistic = bankSpecialAccountStatisticMonthService.GetProjectSpecialAccountStatisticMonthByBankAccountMonth(projectSpecialAccount.BankNo, entity.Month.ToString("yyyyMM")) ?? new BankSpecialAccountStatisticMonth();
        //        }
        //        entity.CurrentActualConstructionMonths = Convert.ToDecimal((endTime - project.ContractStartDate).Days) / Convert.ToDecimal(30);
        //        if (!project.ContractEndDate.HasValue) entity.TotalDuration = 0;
        //        else
        //            entity.TotalDuration = (project.ContractEndDate.Value - project.ContractStartDate).Days / 30;
        //        if (entity.TotalDuration > 0)
        //            entity.TotalAmountDue = Math.Round(Convert.ToDecimal(project.ContractAmount) * Convert.ToDecimal(0.2) / entity.TotalDuration * entity.CurrentActualConstructionMonths, 4);
        //        entity.TotalActualReceipts = Math.Round((bankStatistic.IncomeAmountEnd ?? 0) - (bankStatistic.IncomeAmountStart ?? 0), 4);
        //        if (entity.TotalDuration > 0)
        //            entity.TheoreticalBalance = Math.Round(Convert.ToDecimal(project.ContractAmount) * Convert.ToDecimal(0.2) / entity.TotalDuration, 2);
        //        entity.OnlineAmount = Math.Round((bankStatistic.OnlinePaymentAmountEnd ?? 0) - (bankStatistic.OnlinePaymentAmountStart ?? 0), 4);
        //        entity.OfflineAmount = Math.Round((bankStatistic.OfflinePaymentAmountEnd ?? 0) - (bankStatistic.OfflinePaymentAmountStart ?? 0), 4);
        //        if (entity.TotalAmountDue == entity.TotalActualReceipts)
        //            entity.IncomeStatus = 落实状态.已落实;
        //        else
        //            entity.IncomeStatus = 落实状态.未落实;

        //        #endregion 进账状态

        //        #region 关键岗位考勤状态

        //        var managerMembers = members.Where(a => a.ProjectId == project.ProjectId && (a.PostCategory == 管理岗位类型.项目经理 || a.PostCategory == 管理岗位类型.安全员 || a.PostCategory == 管理岗位类型.技术负责人 || a.PostCategory == 管理岗位类型.总监理工程师));
        //        entity.CheckinStatus = checkinWorkHoursService.GetKeyPositionCheckinStatus(managerMembers, checkinWorkHours, project.ProjectId, true);
        //        entity.ProjectName = project.Name;

        //        #endregion 关键岗位考勤状态

        //        entity.CreateTime = DateTime.Now;
        //        entity.DaysUnderConstruction = reportProjectMonths.Sum(a => a.DaysUnderConstruction);
        //        entity.DaysShutDown = reportProjectMonths.Sum(a => a.DaysUnderConstruction);
        //        entity.NumberAgencyTransactions = 0;
        //        entity.PaymentAmount = 0;
        //        entity.NumberProxyRecipients = 0;
        //        entity.Balance = projectSpecialAccount?.Balance ?? 0;

        //        #region 项目经理考勤天数

        //        var memberid = managerMembers.FirstOrDefault(a => a.PostCategory == 管理岗位类型.项目经理)?.Id;
        //        entity.ProjectManagerAttendanceDays = checkinWorkHours.FirstOrDefault(a => a.MemberId == memberid)?.CheckinDay ?? 0;

        //        #endregion 项目经理考勤天数

        //        #region 技术负责人考勤天数

        //        memberid = managerMembers.FirstOrDefault(a => a.PostCategory == 管理岗位类型.技术负责人)?.Id;
        //        entity.TechnicalManagerAttendanceDays = checkinWorkHours.FirstOrDefault(a => a.MemberId == memberid)?.CheckinDay ?? 0;

        //        #endregion 技术负责人考勤天数

        //        #region 安全员考勤天数

        //        memberid = managerMembers.FirstOrDefault(a => a.PostCategory == 管理岗位类型.安全员)?.Id;
        //        entity.SafetyOfficerAttendanceDays = checkinWorkHours.FirstOrDefault(a => a.MemberId == memberid)?.CheckinDay ?? 0;

        //        #endregion 安全员考勤天数

        //        #region 总监理工程师考勤天数

        //        memberid = managerMembers.FirstOrDefault(a => a.PostCategory == 管理岗位类型.总监理工程师)?.Id;
        //        entity.SupervisionAttendanceDays = checkinWorkHours.FirstOrDefault(a => a.MemberId == memberid)?.CheckinDay ?? 0;

        //        #endregion 总监理工程师考勤天数

        //        reportProjectMonthService.Create(entity);
        //    }
        //    applicationContext.Transaction.Complete();
        //}
        //catch (Exception ex)
        //{
        //    logger.LogError("项目月统计报表执行失败：" + ex.Message);
        //    applicationContext.Transaction.Abort();
        //} 
        #endregion

        return Task.CompletedTask;
    }
}